package com.sofwin.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sofwin.mapper.SysResourceMapper;
import com.sofwin.mapper.SysRoleMapper;
import com.sofwin.mapper.SysRoleResourceMapper;
import com.sofwin.pojo.*;
import com.sofwin.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import java.util.List;

/**
 * @program: ssm-parent
 * @description: 处理角色业务实现类
 * @author: Mr.Gao
 * @create: 2021-04-17 10:52
 **/
@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    private SysRoleMapper mapper;
    @Autowired
    private SysResourceMapper resourceMapper;
    @Autowired
    private SysRoleResourceMapper roleResourceMapper;


    /**
    * @Description: 查询所有角色(sys_user中用到)
    * @return: List<SysRole>
    * @Author: Mr.Gao
    * @Date: 2021/4/17
    */
     /** @Author abiao
     * @Description 查询所有角色(SysUser用到)
     * @Date 2021/4/17 下午 5:26
     * @param
     * @return list 角色信息集合
     */
    @Override
    public List<SysRole> selectAllRoles() {
        List<SysRole> roles = mapper.selectByExample(null);
        return roles;
    }



    /**
    * @Description: 分页查询角色
    * @param role: 角色实体类
    * @param pageNumber: 当前页码
    * @param pageSize: 分页中每页的条数
    * @return: PageInfo<SysRole>
    * @Author: Mr.Gao
    * @Date: 2021/4/17
    */
    @Override
    public PageInfo<SysRole> selectRolesByPage(SysRole role, Integer pageNumber, Integer pageSize) {
        SysRoleExample ex = new SysRoleExample();
        SysRoleExample.Criteria criteria = ex.createCriteria();
        if (role!=null){
            if (role.getRoleName()!=null && !"".equals(role.getRoleName())){
                criteria.andRoleNameLike("%"+role.getRoleName()+"%");
            }
            if (role.getFlag()!=null && role.getFlag()!=0){
                criteria.andFlagEqualTo(role.getFlag());
            }
        }
        PageHelper.startPage(pageNumber, pageSize);
        List<SysRole> roles = mapper.selectByExample(ex);
        return new PageInfo<SysRole>(roles);
    }



    /**
    * @Description: 批量删除角色
    * @param ids: 通过id删除
    * @return: boolean
    * @Author: Mr.Gao
    * @Date: 2021/4/17
    */
    @Override
    public boolean deleteByID(Integer[] ids) {
        int flag = 0;
        for (Integer id:ids){
            flag+=mapper.deleteByPrimaryKey(id);
        }
        return flag==ids.length?true:false;
    }


    /**
    * @Description: 编辑时查询数据（新增）
    * @param id: 通过id选择数据
    * @return: SysRole
    * @Author: Mr.Gao
    * @Date: 2021/4/17
    */
    @Override
    public SysRole selectById(Integer id) {

        return mapper.selectByPrimaryKey(id);
    }



    /**
    * @Description: 保存数据 角色新增/编辑 处理数据
    * @param role: 角色实体类封装
    * @return: boolean
    * @Author: Mr.Gao
    * @Date: 2021/4/17
    */
    @Override
    public boolean saveRole(SysRole role) {
        if (role.getId()!=null){
            return mapper.updateByPrimaryKeySelective(role)==1?true:false;
        }
        return mapper.insertSelective(role)==1?true:false;
    }


    /**
    * @Description: 保存权限，从数据库中增加或者删除一条数据（sys_role_resource）
    * @param roleId: 角色Id
     * @param resourceId: 资源ID
     * @param flag: 状态（是否被选中）
    * @return: boolean
    * @Author: Mr.Gao
    * @Date: 2021/4/17
    */
    @Override
    public boolean savePermission(Integer roleId, Integer resourceId, Integer flag) {
        boolean status= false;
        //获取当前资源
        SysResource currentResource = resourceMapper.selectByPrimaryKey(resourceId);
        if (flag==0){
            // 取消权限

            //判断当前资源是否为父级资源
            if (isParentResource(resourceId)){
                //删除父和子资源
                status=  deleteParentAndChildren(roleId,resourceId);
            }else {
                //判断是否为最后一个子节点
                if (isLastChild(resourceId,roleId)){
                    status=   deleteParentAndChildren(roleId,currentResource.getParentId());
                }else {
                    status=  deleteResourceById(resourceId,roleId);
                }
            }

        }else {
            // 添加权限

            //如果添加的是父节点
            if (isParentResource(resourceId)){
                //添加父节点和子节点
                status=  saveParentAndChildren(roleId,resourceId);
            }else {
                //如果添加的是第一个子节点
                if (isFirstChild(resourceId,roleId)){
                    //保存的第一个节点 ，先保存父节点
                    status = saveRoleResource(currentResource.getParentId(),roleId);
                }
                    status=  saveRoleResource(currentResource.getId(),roleId);
            }

        }

        return status;
    }




    /**
    * @Description: 保存权限，从数据库中增加或者删除一条数据
    * @param roleId: 角色id
     * @param resourceIds: 资源id数组
    * @return: boolean
    * @Author: Mr.Gao
    * @Date: 2021/4/17
    */
    @Override
    public boolean savePermissions(Integer roleId, Integer[] resourceIds) {
        boolean status = false;
        int flag = 0;
        if (resourceIds!=null && resourceIds.length>0){
            SysRoleResourceExample ex = new SysRoleResourceExample();
            SysRoleResourceExample.Criteria criteria = ex.createCriteria();
            criteria.andRoleIdEqualTo(roleId);
            roleResourceMapper.deleteByExample(ex);
            for (Integer resourceId:resourceIds){
                SysRoleResource roleResource = new SysRoleResource();
                roleResource.setRoleId(roleId);
                roleResource.setResourceId(resourceId);
                flag += roleResourceMapper.insertSelective(roleResource);
            }
        }
        if (resourceIds==null || resourceIds.length==0){
            SysRoleResourceExample ex = new SysRoleResourceExample();
            SysRoleResourceExample.Criteria criteria = ex.createCriteria();
            criteria.andRoleIdEqualTo(roleId);
            roleResourceMapper.deleteByExample(ex);
            status=true;
        }else if(flag==resourceIds.length){
            status=true;
        }
        return status;
    }

    /**
     * 添加资源，保存父资源
     * @param parentId
     * @param roleId
     */
    private boolean saveRoleResource(Integer parentId, Integer roleId) {
        SysRoleResource roleResource = new SysRoleResource();
        roleResource.setResourceId(parentId);
        roleResource.setRoleId(roleId);
        int num = roleResourceMapper.insertSelective(roleResource);
        return num==1?true:false;
    }

    /**
     * 添加权限，判断是否为第一个子节点
     * @param resourceId
     * @param roleId
     * @return
     */
    private boolean isFirstChild(Integer resourceId, Integer roleId) {
        SysResource parent = resourceMapper.selectByPrimaryKey(resourceId);
        SysRoleResourceExample example2 = new SysRoleResourceExample();
        SysRoleResourceExample.Criteria criteria1 = example2.createCriteria();
        criteria1.andRoleIdEqualTo(roleId);
        criteria1.andResourceIdEqualTo(parent.getParentId());
        long num = roleResourceMapper.countByExample(example2);
        return num==0?true:false;
    }

    /**
     *  添加权限，保存父资源和子资源
     * @param resourceId
     * @param roleId
     */
    private boolean saveParentAndChildren(Integer roleId,Integer resourceId) {
        int num = roleResourceMapper.saveParentAndChildren(roleId,resourceId);
        return num>0?true:false;
    }

    /**
     * 取消权限，删除当前资源
     * @param resourceId
     * @param roleId
     */
    private boolean deleteResourceById(Integer resourceId, Integer roleId) {
        SysRoleResourceExample ex = new SysRoleResourceExample();
        SysRoleResourceExample.Criteria criteria = ex.createCriteria();
        criteria.andResourceIdEqualTo(resourceId);
        criteria.andRoleIdEqualTo(roleId);
        int num = roleResourceMapper.deleteByExample(ex);
        return num>0?true:false;
    }

    /**
     * 取消权限，判断是否为最后一个子结点
     * @param resourceId
     * @param roleId
     * @return
     */
    private boolean isLastChild(Integer resourceId, Integer roleId) {
        Integer num = roleResourceMapper.selectResourceIsLast(roleId, resourceId);
        return num==1?true:false;
    }

    /**
     * 取消权限，删除父资源和子资源
     * @param roleId
     * @param resourceId
     */
    private boolean deleteParentAndChildren(Integer roleId, Integer resourceId) {
        int num = roleResourceMapper.deleteParentAndChildren(roleId, resourceId);
        return num>0?true:false;
    }

    /**
     * 取消权限，判断当前结点是否为父节点
     * @param resourceId
     * @return
     */
    private boolean isParentResource(Integer resourceId) {
        SysResource resource = resourceMapper.selectByPrimaryKey(resourceId);
        return resource.getParentId()==0?true:false;
    }


}
